package ccm.component.oscilloscope;

import java.util.concurrent.ConcurrentHashMap;

abstract public class OscilloscopeDataManager
{
    /**
     * 用于保存接收到的数据
     */
    protected final ChunkList<TimeAndData> dataList;
    protected final ConcurrentHashMap<Integer,String[]> nameMap;
    protected boolean fastUpdate;

    protected OscilloscopeDataManager()
    {
        dataList=new ChunkList<>();
        nameMap=new ConcurrentHashMap<>();
        fastUpdate=true;
    }

    /**
     * 清空数据
     */
    public void clear()
    {
        dataList.clear();
        nameMap.clear();
    }

    /**
     * 获取数据行数
     */
    public int getDataLength()
    {
        return dataList.size();
    }

    public String getColumnName(int i,int column)
    {
        TimeAndData timeAndData=getTimeAndData(i);
        if(timeAndData instanceof TimeNameAndData)
        {
            final String[] split=nameMap.get(((TimeNameAndData)timeAndData).getNameHash());
            if(split==null||column>=split.length)
            {
                return getColumnName(column);
            }
            return String.format("%2d:%s",column,split[column]);
        }
        else
        {
            return getColumnName(column);
        }
    }

    /**
     * 获取时间和数据
     *
     * @param i 数据行
     * @return
     */
    public TimeAndData getTimeAndData(int i)
    {
        return (i<0||i>=dataList.size())?null:dataList.get(i);
    }

    /**
     * 获取列的名字
     *
     * @param column 列
     * @return 注释
     */
    public String getColumnName(int column)
    {
        return String.format("Data%d",column);
    }

    /**
     * 获取第i行数据第column列是不是可用的数据点
     *
     * @param i      数据行
     * @param column 数据列
     * @return 是否可用
     */
    public boolean isColumnEnabled(int i,int column)
    {
        if(column>=getDataColumn())
        {
            return false;
        }
        final TimeAndData timeAndData=getTimeAndData(i);
        return timeAndData!=null&&column<timeAndData.getData().length;
    }

    /**
     * 获取第i行数据和前一行是不是连续的
     *
     * @param i 数据行
     * @return 是否连续
     * @implNote 特别的我们认为第0行和前一行是连续的，即便他没有前一行
     */
    public boolean isContinuous(int i)
    {
        if(i==0) return true;
        final TimeAndData timeAndData1=getTimeAndData(i-1), timeAndData2=getTimeAndData(i);
        if(timeAndData1==null||timeAndData2==null) return false;
        if((timeAndData1 instanceof TimeNameAndData)!=(timeAndData2 instanceof TimeNameAndData)) return false;
        if(timeAndData1.getData().length!=timeAndData2.getData().length) return false;
        return !(timeAndData1 instanceof TimeNameAndData)||(((TimeNameAndData)timeAndData1).getNameHash()==((TimeNameAndData)timeAndData1).getNameHash());
    }

    /**
     * 获取一共有几列
     *
     * @return 列数
     */
    abstract int getDataColumn();

    public void setFastUpdate(boolean fastUpdate)
    {
        this.fastUpdate=fastUpdate;
    }

    public long getTimeUs(int i)
    {
        final TimeAndData timeAndData=getTimeAndData(i);
        return (timeAndData==null)?0:timeAndData.getTime();
    }

    public float getY(int i,int column)
    {
        final TimeAndData timeAndData=getTimeAndData(i);
        return (timeAndData==null||timeAndData.getData().length<=column)?0:timeAndData.getData()[column];
    }
}
